/**
 * 
 */
package any.tag.server.impl;

import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
import org.springframework.transaction.annotation.Transactional;

import any.tag.Tag;
import any.tag.TagItem;
import any.tag.dao.TagDao;
import any.tag.dao.TagItemDao;
import any.tag.server.TagService;

/**
 * TODO: Doc me
 * 
 * @author keke <keke@codehaus.org>
 * @version
 * @revision $Revision:$
 */
public class DefaultTagService implements TagService {
    private TagDao     tagDao;
    private TagItemDao tagItemDao;

    /*
     * (non-Javadoc)
     * 
     * @see any.tag.server.TagService#getAllTags()
     */
    @Transactional(readOnly = true)
    public Collection<Tag> getAllTags() {
        return tagDao.listAll();
    }

    @Transactional(readOnly = true)
    public Collection<TagItem> getTagItemsByAbout(final URI about) {
        Validate.notNull(about);
        return tagItemDao.getTagItems(about);
    }

    @Transactional(readOnly = true)
    public Collection<TagItem> getTagItemsByName(final String tagName) {
        Validate.notNull(tagName);
        return tagItemDao.getTagItems(tagDao.getTag(tagName));
    }

    public void setTagDao(final TagDao tagDao) {
        this.tagDao = tagDao;
    }

    public void setTagItemDao(final TagItemDao tagItemDao) {
        this.tagItemDao = tagItemDao;
    }

    @Transactional(readOnly = false)
    public Collection<TagItem> tag(final String[] tagNames, final URI uri) {
        Validate.notNull(tagNames);
        Validate.notNull(uri);
        final Collection<TagItem> oldItems = tagItemDao.getTagItems(uri);
        final List<TagItem> newItems = new ArrayList<TagItem>();
        for (String tagName : tagNames) {
            tagName = tagName.trim();
            if (StringUtils.isEmpty(tagName)) {
                continue;
            }
            Tag tag = tagDao.getTag(tagName);
            if (tag == null) {
                tag = new Tag(tagName);
                tagDao.save(tag);
            }
            TagItem item = tagItemDao.getTagItem(tag, uri);
            if (item == null) {
                item = new TagItem(tag, uri);
                tagItemDao.save(item);
            }
            newItems.add(item);
            oldItems.remove(item);
        }
        for (final TagItem item : oldItems) {
            tagItemDao.delete(item);
        }
        return newItems;

    }

}
